// CVisMatrix.h
// Developed by Yang Yu (yuy@janelia.hhmi.org), Sept 27, 2012
// 

#ifndef __CVISMATRIX_H__
#define __CVISMATRIX_H__

#include "CVisUtility.h"

//------------------------------------------------------------------
/// Matrix class
//
//  Definition:
//
//  Mrxc
//  ----------> r
//  |
//  |
//  |
//  c
//
//  c++ code style: for(j in c) for(i in r) cout<<M.v[j][i]<<endl;
//
//  Anxm * Bdxn = Cdxm
//  c++ code example: B.prod(A); C.copy(B); A.clean(); B.clean();
//
//------------------------------------------------------------------

template<class Tdata, class Tidx>
class Y_MAT
{
public:
    Y_MAT();
    Y_MAT(Tdata *pInput, Tidx dimx, Tidx dimy);

    ~Y_MAT();

public:
    void init(Tidx dimx, Tidx dimy, Tdata value);
    void clone(Y_MAT pIn, bool t);
    void copy(Y_MAT M);
    void clean();
    void zeros();
    void unit();

    void prod(Y_MAT M);
    void transpose();
    void pseudoinverse();

    Tdata pythagorean(Tdata a, Tdata b);
    void svd(Y_MAT U, Y_MAT S, Y_MAT V);
    void lu(Y_MAT a, Y_MAT b);

    void vectorMul(REAL *in, REAL *&out);
    void normalize3DAffine(Y_MAT M);
    void getRigid(Y_MAT M1, Y_MAT M2);

    void assign(const Y_MAT M) const;
    void setVal(Tidx r, Tidx c, Tdata val);

    void sortEigenVectors(Y_MAT E);
    void sortEigenValues();

public:
    Tdata *p;
    Tdata **v;
    Tidx row, column;

};

//----------------------------
#include "CVisMatrix.hpp"
//----------------------------

#endif //__CVISMATRIX_H__
